package kr.co.redcircle.console.dialog;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

public class ConsoleDialog extends Dialog {

	private static final String CONSOLE_CONFIG_XML = "/kr/co/redcircle/console/config/consoleConfig.xml";
	protected Object result;
	protected Shell shell;
	protected Shell parentShell;
	private Rectangle pRenctangle = null;
	private ConsoleDialogContents targetComposite;
	private static SAXBuilder builder = new SAXBuilder();
    private static Document document = null;

    static{
		try {
			document = builder.build(ConsoleDialog.class.getResourceAsStream(CONSOLE_CONFIG_XML));
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
	/**
	 * Create the dialog.
	 * @param parent
	 * @param style
	 * @param point 
	 */
	public ConsoleDialog(Shell parent, int style) {
		super(parent, style);
		parentShell = parent;
	}

	public void setComposite(ConsoleDialogContents composite){
		this.targetComposite = composite;
		System.out.println("setComposite.targetComposite : " + targetComposite);
	}


	/**
	 * Open the dialog.
	 * @return the result
	 */
	public Object open() {
		createContents();		
		shell.open();
		shell.layout();
		Display display = getParent().getDisplay();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		
		System.out.println("createContents.targetComposite : " + this.targetComposite);
		System.out.println("createContents.targetComposite.getDialogSize() : " + this.targetComposite.getDialogSize());
		
		shell = new Shell(getParent(), getStyle());
		shell.setSize(this.targetComposite.getDialogSize());
		shell.setText(getText());
		
		targetComposite.createContents(shell);
		
		reLocationShell();
	}

	private void reLocationShell() {
		pRenctangle = parentShell.getBounds();
		Rectangle nowRectanle = shell.getBounds();
		nowRectanle.x = pRenctangle.x + ((pRenctangle.width - nowRectanle.width) / 2);
		nowRectanle.y = pRenctangle.y + ((pRenctangle.height - nowRectanle.height)	/ 2);
		shell.setBounds(nowRectanle);
	}

	public void setComposite(ConsoleDialogContents contents, Rectangle rectangle) {
		//contents.setBounds(rectangle);
		setComposite(contents);
	}

	public static ConsoleDialogContents getContents(Shell shell, String contentsID) {
		Object searchResult = null;
		
		try {
			searchResult = XPath.selectSingleNode(document, "//collection[@type='dialog']/composite[@id='" + contentsID + "']");
		} catch (JDOMException e) {
			e.printStackTrace();
		}
		
		if (searchResult != null){
			
			Element sRElement = (Element)searchResult;
			Element dialogElement = sRElement.getChild("dialog");
			Element contentsElement = sRElement.getChild("contents");

			String className = sRElement.getAttributeValue("class");
			System.out.println("className : " + className);
			int diagX = Integer.parseInt(dialogElement.getAttributeValue("x"));
			int diagY = Integer.parseInt(dialogElement.getAttributeValue("y"));
			int contX = Integer.parseInt(contentsElement.getAttributeValue("x"));
			int contY = Integer.parseInt(contentsElement.getAttributeValue("y"));
			int contWith = Integer.parseInt(contentsElement.getAttributeValue("width"));
			int contHeight = Integer.parseInt(contentsElement.getAttributeValue("height"));
			
			Class<?>[] parameterTypes = new Class<?>[]{Composite.class, Integer.class, Point.class, Rectangle.class};
			Object[] parameterValues = new Object[]{shell, SWT.NONE, new Point(diagX, diagY), new Rectangle(contX,  contY, contWith, contHeight)};
			
			Class<?> contentsClass;
			
			try {
				contentsClass = Class.forName(className);
				Constructor<?> constructor = contentsClass.getConstructor(parameterTypes);
				
				if (constructor != null){
					ConsoleDialogContents contents = (ConsoleDialogContents)constructor.newInstance(parameterValues);
					return contents;
				}
				
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
			
		}

		return null;
	}

	public static ConsoleDialog getDialog(Shell shell, String contentsID) {
		ConsoleDialog diag = new ConsoleDialog(shell, SWT.DIALOG_TRIM|SWT.APPLICATION_MODAL);
		diag.setComposite(ConsoleDialog.getContents(shell, contentsID));
		System.out.println("getDialog(Shell shell, String contentsID) : " + diag);
		return diag;
	}

	public static ConsoleDialog getAlertDialog(Shell shell, String contentsID, AlertMessageContent mdc) {
		return getDialog(shell, contentsID).setMessageContent(mdc);
	}

	private ConsoleDialog setMessageContent(AlertMessageContent mdc) {
	
		getComposite().setMessageContents(mdc);
		
		return this;
	}

	private ConsoleDialogContents getComposite() {
		System.out.println("getComposite() : " + this.targetComposite);
		return this.targetComposite;
	}
}
